﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.Revit;

namespace YArchitech.Plumbing
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class DrainageSystemCal : HYNoTranExternalCommand
	{
		public override Result HYExecute()
		{
			HYSystemCal hysystemCal = new HYSystemCal();
			SearchSys searchSys = new SearchSys();
			string prompt = "请选择要计算系统的入口管道远端: ";
			if (!searchSys.Run(base.UiDoc, prompt))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			if (!searchSys.DumpIntoPipeSystem(out hysystemCal, base.UiDoc.Document))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			hysystemCal.systemType = HYSystemCal.SystemType.Drainage;
			if (!hysystemCal.CheckSelectSystem())
			{
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			this.GetPipeDNForPipe(hysystemCal);
			if (!hysystemCal.CheckAllBathroomIsDef())
			{
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			MainForm mainForm = new MainForm(base.Doc, base.UiDoc, hysystemCal);
			for (;;)
			{
				DialogResult dialogResult = mainForm.ShowDialog();
				if (dialogResult == DialogResult.Abort)
				{
					if (mainForm.beMinimize)
					{
						this.BeMinimizeOperator(base.UiDoc, mainForm.ElemIds);
						continue;
					}
					try
					{
						hysystemCal = new HYSystemCal();
						searchSys = new SearchSys();
						if (!searchSys.Run(base.UiDoc, prompt))
						{
							return Autodesk.Revit.UI.Result.Cancelled;
						}
						if (searchSys.DumpIntoPipeSystem(out hysystemCal, base.UiDoc.Document))
						{
							hysystemCal.systemType = HYSystemCal.SystemType.Drainage;
							this.GetPipeDNForPipe(hysystemCal);
							mainForm.RefreshTheHYSystemCal(hysystemCal);
						}
						continue;
					}
					catch (Exception ex)
					{
						YJKMessageBox.Show(ex.Message);
						continue;
					}
				}
				if (dialogResult != DialogResult.OK)
				{
					break;
				}
				hysystemCal = new HYSystemCal();
				hysystemCal = mainForm.hySystemCal;
				if (this.ReturnDataToDocument(hysystemCal.PipeCals, "排水计算"))
				{
					YJKMessageBox.Information("赋回成功");
				}
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public bool BeMinimizeOperator(UIDocument uiDoc, List<ElementId> ElementIds)
		{
			HYTwinkle hytwinkle = new HYTwinkle();
			hytwinkle.View = uiDoc.ActiveView;
			hytwinkle.Ids = ElementIds;
			hytwinkle.Start();
			if (this.BeMinimize(uiDoc))
			{
				hytwinkle.Dispose();
			}
			return true;
		}

		private bool BeMinimize(UIDocument uiDoc)
		{
			bool result;
			try
			{
				uiDoc.Selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)0, "查看状态，不能进行任何操作！");
				result = true;
			}
			catch (Exception)
			{
				result = true;
			}
			return result;
		}

		public override void FilterProcess()
		{
			base.FilterViewType.Add(1);
			base.FilterViewType.Add(2);
			base.FilterViewType.Add(4);
			base.FilterProcess();
		}

		public void GetPipeDNForPipe(HYSystemCal hySystemCal)
		{
			if (hySystemCal.PipeCals.Count > 0)
			{
				foreach (HYPipeCal hypipeCal in hySystemCal.PipeCals)
				{
					Element elementById = base.Doc.GetElementById(new ElementId(hypipeCal.Id));
					if (elementById == null)
					{
						IEnumerator enumerator2 = RevitUtility.LinkedDocuments.GetEnumerator();
						bool flag = enumerator2.MoveNext();
						while (flag)
						{
							elementById = (enumerator2.Current as LinkedDocument).Document.GetElementById(new ElementId(hypipeCal.Id));
							if (elementById != null)
							{
								break;
							}
							flag = enumerator2.MoveNext();
						}
					}
					if (elementById != null)
					{
						IEnumerable<MEPSize> allMepSize = UnifiedModified.GetAllMepSize((elementById as Pipe).PipeType);
						hypipeCal.dirDNArray = new Dictionary<int, double>();
						foreach (MEPSize mepsize in allMepSize)
						{
							hypipeCal.dirDNArray.Add((int)Math.Ceiling(304.7 * mepsize.NominalDiameter), Math.Round(304.7 * mepsize.InnerDiameter, 2));
						}
					}
				}
			}
		}

		private Dictionary<PipeType, IList<ElementId>> GetPipeTypeFirstFittings(List<HYPipeCal> list)
		{
			Dictionary<PipeType, IList<ElementId>> dictionary = new Dictionary<PipeType, IList<ElementId>>();
			foreach (HYPipeCal hypipeCal in list)
			{
				Pipe pipe = base.Doc.GetElement(new ElementId(hypipeCal.Id)) as Pipe;
				if (pipe != null && hypipeCal.endSprinkler == null)
				{
					PipeType pipeType = pipe.PipeType;
					IList<ElementId> segmentFitting = UnifiedModified.GetSegmentFitting(pipeType, 2);
					if (dictionary.Count < 1)
					{
						dictionary.Add(pipe.PipeType, segmentFitting);
					}
					else if (!dictionary.Keys.ToList<PipeType>().Contains(pipeType))
					{
						dictionary.Add(pipe.PipeType, segmentFitting);
					}
				}
			}
			return dictionary;
		}

		public bool ReturnDataToDocument(List<HYPipeCal> list, string operationName)
		{
			bool flag = true;
			if (list.Count <= 0)
			{
				return flag;
			}
			Transaction transaction = new Transaction(base.Doc, "图面赋回");
			transaction.Start();
			Dictionary<PipeType, IList<ElementId>> pipeTypeFirstFittings = this.GetPipeTypeFirstFittings(list);
			SubTransaction subTransaction = new SubTransaction(base.Doc);
			subTransaction.Start();
			List<HYPipeCal> list2 = new List<HYPipeCal>();
			foreach (HYPipeCal hypipeCal in list)
			{
				Element element = base.Doc.GetElement(new ElementId(hypipeCal.Id));
				if (element != null && hypipeCal.endSprinkler == null)
				{
					Parameter parameter = element.GetParameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM);
					if (parameter != null)
					{
						parameter.Set((double)hypipeCal.nDN / 304.8);
					}
					ConnectorSetIterator connectorSetIterator = DrainageSystemCal.GetConnectors(element).ForwardIterator();
					while (connectorSetIterator.MoveNext())
					{
						object obj = connectorSetIterator.Current;
						Connector connector = obj as Connector;
						if (connector.IsConnected)
						{
							Connector connectConnector = this.GetConnectConnector(connector);
							FamilyInstance familyInstance = connectConnector.Owner as FamilyInstance;
							MechanicalFitting mechanicalFitting = familyInstance.MEPModel as MechanicalFitting;
							if (mechanicalFitting != null && mechanicalFitting.PartType == 6)
							{
								PipeType pipeType = (element as Pipe).PipeType;
								UnifiedModified.ClearSegmentFitting(pipeType, 2);
								UnifiedModified.SetSegmentFitting(pipeType, 2, familyInstance.Symbol.Id, "盈建科三通");
							}
							if (connectConnector != null)
							{
								BuiltInCategory integerValue = connectConnector.Owner.Category.Id.IntegerValue;
								if (integerValue == -2008055 || integerValue == -2008044 || integerValue == -2008049)
								{
									connectConnector.Radius = (double)hypipeCal.nDN / 304.8 / 2.0;
								}
							}
						}
					}
					base.Doc.Regenerate();
				}
				else
				{
					list2.Add(hypipeCal);
				}
			}
			subTransaction.Commit();
			subTransaction = new SubTransaction(base.Doc);
			subTransaction.Start();
			foreach (KeyValuePair<PipeType, IList<ElementId>> keyValuePair in pipeTypeFirstFittings)
			{
				PipeType key = keyValuePair.Key;
				IList<ElementId> value = keyValuePair.Value;
				UnifiedModified.ClearSegmentFitting(key, 2);
				for (int i = 0; i < value.Count; i++)
				{
					UnifiedModified.SetSegmentFitting(key, 2, value[i], "水管三通" + i);
				}
			}
			subTransaction.Commit();
			transaction.Commit();
			List<LinkedDocument> list3 = RevitUtility.LinkedDocuments.ToList<LinkedDocument>();
			if (list3.Count > 0 && YJKMessageBox.Show("当前文档存在链接文件，是否保存链接文件改动数据？", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
			{
				string text = base.Doc.Title;
				string arg = text;
				if (text.LastIndexOf(".rvt") > 0)
				{
					arg = text.Substring(0, text.LastIndexOf(".rvt"));
				}
				string text2 = string.Format("{0}_InFile_{1}.xml", operationName, arg);
				string empty = string.Empty;
				SaveFileDialog saveFileDialog = new SaveFileDialog();
				saveFileDialog.Filter = "数据更新文件|*.xml";
				if (!string.IsNullOrEmpty(this.lastSelectedPath))
				{
					saveFileDialog.InitialDirectory = this.lastSelectedPath;
				}
				saveFileDialog.RestoreDirectory = true;
				saveFileDialog.FilterIndex = 1;
				saveFileDialog.FileName = text2;
				if (saveFileDialog.ShowDialog() == DialogResult.OK)
				{
					try
					{
						text2 = saveFileDialog.FileName;
						this.lastSelectedPath = text2;
						List<string> list4 = new List<string>();
						foreach (LinkedDocument linkedDocument in list3)
						{
							text = linkedDocument.Document.Title;
							if (text.LastIndexOf(".rvt") > 0)
							{
								text = text.Substring(0, text.LastIndexOf(".rvt"));
							}
							list4.Add(text);
						}
						flag &= HYUpdateLinkedDocXML.AddRootAndFileListNodes(text2, MajorSystemType.PlumbingSystem, list4);
						foreach (LinkedDocument linkedDocument2 in list3)
						{
							text = linkedDocument2.Document.Title;
							if (text.LastIndexOf(".rvt") > 0)
							{
								text = text.Substring(0, text.LastIndexOf(".rvt"));
							}
							List<HYUpdateElementInfo> list5 = new List<HYUpdateElementInfo>();
							foreach (HYPipeCal hypipeCal2 in list2)
							{
								Element elementById = linkedDocument2.Document.GetElementById(new ElementId(hypipeCal2.Id));
								if (elementById != null)
								{
									if (hypipeCal2.endSprinkler == null)
									{
										HYUpdateElementInfo hyupdateElementInfo = new HYUpdateElementInfo();
										hyupdateElementInfo.DocumentTitle = text;
										hyupdateElementInfo.ElementID = hypipeCal2.Id;
										Category category = elementById.Document.Settings.Categories.get_Item(BuiltInCategory.OST_PipeCurves);
										hyupdateElementInfo.CategoryName = category.Name;
										hyupdateElementInfo.PipeDN = hypipeCal2.nDN;
										list5.Add(hyupdateElementInfo);
									}
									else if (hypipeCal2.endSprinkler.IsInArea)
									{
										HYUpdateElementInfo hyupdateElementInfo2 = new HYUpdateElementInfo();
										hyupdateElementInfo2.DocumentTitle = text;
										hyupdateElementInfo2.ElementID = hypipeCal2.endSprinkler.Id;
										Category category2 = elementById.Document.Settings.Categories.get_Item(BuiltInCategory.OST_Sprinklers);
										hyupdateElementInfo2.CategoryName = category2.Name;
										hyupdateElementInfo2.FLow = hypipeCal2.Flow;
										list5.Add(hyupdateElementInfo2);
									}
								}
							}
							flag &= HYUpdateLinkedDocXML.AddElementListToXML(text2, text, list5);
						}
					}
					catch (Exception ex)
					{
						ex.ToString();
						flag = false;
						YJKMessageBox.Error("保存链接文件数据失败！");
					}
				}
			}
			return flag;
		}

		public static ConnectorSet GetConnectors(Element element)
		{
			if (element == null)
			{
				return null;
			}
			FamilyInstance familyInstance = element as FamilyInstance;
			if (familyInstance != null && familyInstance.MEPModel != null)
			{
				return familyInstance.MEPModel.ConnectorManager.Connectors;
			}
			MEPSystem mepsystem = element as MEPSystem;
			if (mepsystem != null)
			{
				return mepsystem.ConnectorManager.Connectors;
			}
			MEPCurve mepcurve = element as MEPCurve;
			if (mepcurve != null)
			{
				return mepcurve.ConnectorManager.Connectors;
			}
			return null;
		}

		public Connector GetConnectConnector(Connector connector)
		{
			Connector result = null;
			if (connector != null && connector.IsConnected)
			{
				ConnectorSetIterator connectorSetIterator = connector.AllRefs.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector connector2 = obj as Connector;
					if (connector2 != null && connector2.Owner.UniqueId != connector.Owner.UniqueId && ((int)connector2.ConnectorType == 1 || (int)connector2.ConnectorType == 2 || (int)connector2.ConnectorType == 19))
					{
						result = connector2;
						break;
					}
				}
			}
			return result;
		}

		protected string lastSelectedPath = string.Empty;
	}
}
